﻿using Dubbo.Common.DynamicProxy;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.Composition;
using Dubbo.Common.Utils;

namespace Dubbo.Rpc.Proxy
{
    [Export(typeof(IProxyFactory))]
    [ExportMetadata("Name", "transparent")]
    public class TransparentProxyFactory : IProxyFactory
    {
        public T GetProxy<T>(IInvoker<T> invoker)
        {
            return ProxyGenerator.CreateProxy<T>(new InvokerInvocationHandler<T>(invoker));
        }

        public IInvoker<T> GetInvoker<T>(T proxy, URL url)
        {
            return new DefaultProxyInvoker<T>(proxy, url);
        }

        class DefaultProxyInvoker<T> : AbstractProxyInvoker<T>
        {
            public DefaultProxyInvoker(T proxy, URL url)
                : base(proxy, url)
            {
            }

            protected override object DoInvoke(T proxy, string methodName, Type[] parameterTypes, object[] arguments)
            {
                var method = TypeUtils.GetMethod(typeof(T), methodName, parameterTypes);
                return method.Invoke(proxy, arguments);
            }
        }
    }
}
